from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session, joinedload
from typing import List, Optional

from database import get_db
from models.detection_model import DetectionModel, ModelVersion
from schemas.detection_model import (
    DetectionModelCreate, DetectionModelUpdate, DetectionModelSchema, DetectionModelWithVersions,
    ModelVersionCreate, ModelVersionUpdate, ModelVersionSchema
)
from schemas import ResponseModel, PaginatedResponse
from api.deps import get_current_active_user
from models.user import User

router = APIRouter()


# ===================== 检测模型相关接口 =====================

@router.post("", response_model=ResponseModel[DetectionModelSchema], status_code=201, tags=["检测模型管理"])
async def create_detection_model(
    model_in: DetectionModelCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """创建检测模型"""
    # 检查名称是否已存在
    if db.query(DetectionModel).filter(DetectionModel.name == model_in.name).first():
        raise HTTPException(status_code=400, detail="模型名称已存在")
    
    db_model = DetectionModel(**model_in.model_dump())
    db.add(db_model)
    db.commit()
    db.refresh(db_model)
    return ResponseModel(data=db_model)


@router.get("", response_model=ResponseModel[PaginatedResponse[DetectionModelSchema]], tags=["检测模型管理"])
async def get_detection_models(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页数量"),
    name: Optional[str] = Query(None, description="模型名称搜索"),
    format: Optional[str] = Query(None, description="模型格式搜索"),
    is_active: Optional[bool] = Query(None, description="是否激活"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """获取检测模型列表"""
    query = db.query(DetectionModel).options(joinedload(DetectionModel.current_version))
    
    # 添加过滤条件
    if name:
        query = query.filter(DetectionModel.name.contains(name))
    if format:
        query = query.filter(DetectionModel.format.contains(format))
    if is_active is not None:
        query = query.filter(DetectionModel.is_active == is_active)
    
    # 计算总数
    total = query.count()
    
    # 分页
    items = query.offset((page - 1) * page_size).limit(page_size).all()
    
    return ResponseModel(
        data=PaginatedResponse(
            items=items,
            total=total,
            page=page,
            page_size=page_size
        )
    )


@router.get("/{model_id}", response_model=ResponseModel[DetectionModelWithVersions], tags=["检测模型管理"])
async def get_detection_model(
    model_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """获取检测模型详情（包含所有版本）"""
    model = db.query(DetectionModel).options(
        joinedload(DetectionModel.versions),
        joinedload(DetectionModel.current_version)
    ).filter(DetectionModel.id == model_id).first()
    
    if not model:
        raise HTTPException(status_code=404, detail="模型不存在")
    
    return ResponseModel(data=model)


@router.put("/{model_id}", response_model=ResponseModel[DetectionModelSchema], tags=["检测模型管理"])
async def update_detection_model(
    model_id: int,
    model_in: DetectionModelUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """更新检测模型"""
    model = db.query(DetectionModel).filter(DetectionModel.id == model_id).first()
    
    if not model:
        raise HTTPException(status_code=404, detail="模型不存在")
    
    # 检查名称是否与其他模型冲突
    if model_in.name and model_in.name != model.name:
        if db.query(DetectionModel).filter(DetectionModel.name == model_in.name, DetectionModel.id != model_id).first():
            raise HTTPException(status_code=400, detail="模型名称已存在")
    
    # 检查current_version_id是否属于该模型
    if model_in.current_version_id:
        version = db.query(ModelVersion).filter(
            ModelVersion.id == model_in.current_version_id,
            ModelVersion.model_id == model_id
        ).first()
        if not version:
            raise HTTPException(status_code=400, detail="指定的版本不属于该模型")
    
    # 更新模型
    update_data = model_in.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(model, field, value)
    
    db.commit()
    db.refresh(model)
    
    # 重新加载关联数据
    model = db.query(DetectionModel).options(
        joinedload(DetectionModel.current_version)
    ).filter(DetectionModel.id == model_id).first()
    
    return ResponseModel(data=model)


@router.delete("/{model_id}", response_model=ResponseModel[dict], tags=["检测模型管理"])
async def delete_detection_model(
    model_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """删除检测模型"""
    model = db.query(DetectionModel).filter(DetectionModel.id == model_id).first()
    
    if not model:
        raise HTTPException(status_code=404, detail="模型不存在")
    
    db.delete(model)
    db.commit()
    
    return ResponseModel(data={"message": "模型删除成功"})


# ===================== 模型版本相关接口 =====================

@router.post("/{model_id}/versions", response_model=ResponseModel[ModelVersionSchema], status_code=201, tags=["检测模型管理"])
async def create_model_version(
    model_id: int,
    version_in: ModelVersionCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """为检测模型创建新版本"""
    # 检查模型是否存在
    model = db.query(DetectionModel).filter(DetectionModel.id == model_id).first()
    if not model:
        raise HTTPException(status_code=404, detail="模型不存在")
    
    # 确保model_id一致
    if version_in.model_id != model_id:
        raise HTTPException(status_code=400, detail="版本的model_id必须与URL中的model_id一致")
    
    # 检查版本名称是否已存在于该模型
    if db.query(ModelVersion).filter(
        ModelVersion.model_id == model_id,
        ModelVersion.version_name == version_in.version_name
    ).first():
        raise HTTPException(status_code=400, detail="该模型下已存在相同名称的版本")
    
    # 检查版本号是否已存在于该模型
    if db.query(ModelVersion).filter(
        ModelVersion.model_id == model_id,
        ModelVersion.version_code == version_in.version_code
    ).first():
        raise HTTPException(status_code=400, detail="该模型下已存在相同版本号")
    
    db_version = ModelVersion(**version_in.model_dump())
    db.add(db_version)
    
    # 如果是第一个版本，自动设为当前版本
    if not model.current_version_id:
        model.current_version_id = db_version.id
    
    db.commit()
    db.refresh(db_version)
    return ResponseModel(data=db_version)


@router.get("/{model_id}/versions", response_model=ResponseModel[List[ModelVersionSchema]], tags=["检测模型管理"])
async def get_model_versions(
    model_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """获取模型的所有版本"""
    # 检查模型是否存在
    model = db.query(DetectionModel).filter(DetectionModel.id == model_id).first()
    if not model:
        raise HTTPException(status_code=404, detail="模型不存在")
    
    versions = db.query(ModelVersion).filter(
        ModelVersion.model_id == model_id
    ).order_by(ModelVersion.created_at.desc()).all()
    
    return ResponseModel(data=versions)


@router.put("/versions/{version_id}", response_model=ResponseModel[ModelVersionSchema], tags=["检测模型管理"])
async def update_model_version(
    version_id: int,
    version_in: ModelVersionUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """更新模型版本"""
    version = db.query(ModelVersion).filter(ModelVersion.id == version_id).first()
    
    if not version:
        raise HTTPException(status_code=404, detail="版本不存在")
    
    # 检查版本名称是否与同模型下其他版本冲突
    if version_in.version_name and version_in.version_name != version.version_name:
        if db.query(ModelVersion).filter(
            ModelVersion.model_id == version.model_id,
            ModelVersion.version_name == version_in.version_name,
            ModelVersion.id != version_id
        ).first():
            raise HTTPException(status_code=400, detail="该模型下已存在相同名称的版本")
    
    # 检查版本号是否与同模型下其他版本冲突
    if version_in.version_code and version_in.version_code != version.version_code:
        if db.query(ModelVersion).filter(
            ModelVersion.model_id == version.model_id,
            ModelVersion.version_code == version_in.version_code,
            ModelVersion.id != version_id
        ).first():
            raise HTTPException(status_code=400, detail="该模型下已存在相同版本号")
    
    # 更新版本
    update_data = version_in.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(version, field, value)
    
    db.commit()
    db.refresh(version)
    return ResponseModel(data=version)


@router.delete("/versions/{version_id}", response_model=ResponseModel[dict], tags=["检测模型管理"])
async def delete_model_version(
    version_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """删除模型版本"""
    version = db.query(ModelVersion).filter(ModelVersion.id == version_id).first()
    
    if not version:
        raise HTTPException(status_code=404, detail="版本不存在")
    
    # 检查是否为当前使用的版本
    model = db.query(DetectionModel).filter(DetectionModel.current_version_id == version_id).first()
    if model:
        # 如果是当前版本，删除时需要重新设置当前版本为最新的其他版本
        latest_version = db.query(ModelVersion).filter(
            ModelVersion.model_id == version.model_id,
            ModelVersion.id != version_id,
            ModelVersion.is_active == True
        ).order_by(ModelVersion.created_at.desc()).first()
        
        model.current_version_id = latest_version.id if latest_version else None
    
    db.delete(version)
    db.commit()
    
    return ResponseModel(data={"message": "版本删除成功"})


@router.post("/versions/{version_id}/activate", response_model=ResponseModel[DetectionModelSchema], tags=["检测模型管理"])
async def activate_model_version(
    version_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """激活模型版本（设置为当前使用版本）"""
    version = db.query(ModelVersion).filter(ModelVersion.id == version_id).first()
    
    if not version:
        raise HTTPException(status_code=404, detail="版本不存在")
    
    if not version.is_active:
        raise HTTPException(status_code=400, detail="版本未激活，无法设为当前版本")
    
    # 更新模型的当前版本
    model = db.query(DetectionModel).filter(DetectionModel.id == version.model_id).first()
    model.current_version_id = version_id
    
    db.commit()
    db.refresh(model)
    
    # 重新加载关联数据
    model = db.query(DetectionModel).options(
        joinedload(DetectionModel.current_version)
    ).filter(DetectionModel.id == version.model_id).first()
    
    return ResponseModel(data=model)